#!/bin/bash

set +x
set -e

if [ -z "$1" ]
	then
		echo "$0 <path-to-qemu-binary>"
		exit
fi

binary=$1

function disass
{
	section=$1
	echo "Disassembling $section..." >&2
	dump=$(mktemp)
	objdump -d -j $section $binary > $dump
	echo $dump
}

function section_addr
{
	section=$1
	readelf -S  $binary | grep .$section | awk '{print $4}'
}

function symbol_reloc
{
	symbol=$1
	objdump -R $binary | grep "\<$symbol\>" | awk '{print $1}'
}

function dynamic_symbol_addr
{
	symbol=$1
	cat $plt | grep "# $(symbol_reloc $symbol | sed 's/^0*//')" | awk '{print $1}' | sed 's/:$//'
}

function static_symbol_addr
{
	symbol=$1
	cat $text | grep "\<$symbol>:" | awk '{print $1}'
}

function format
{
	xargs -I{} printf "0x%0$1x" 0x{}
}

plt=$(readelf -S $binary | grep plt | tail -n 1 | awk '{print $2}')
plt=$(disass $plt)
text=$(disass .text)

echo "#define TEXT_ADDR           $(section_addr text | format 16)"
echo "#define mprotect_ADDR       $(dynamic_symbol_addr mprotect | format 16)"
echo "#define madvise_ADDR        $(dynamic_symbol_addr madvise | format 16)"
echo "#define malloc_ADDR         $(dynamic_symbol_addr malloc | format 16)"
echo "#define open_ADDR           $(dynamic_symbol_addr open64 | format 16)"
echo "#define close_ADDR          $(dynamic_symbol_addr close | format 16)"
echo "#define read_ADDR           $(dynamic_symbol_addr read | format 16)"
echo "#define write_ADDR          $(dynamic_symbol_addr write | format 16)"
echo "#define dup2_ADDR           $(dynamic_symbol_addr dup2 | format 16)"
echo "#define pipe_ADDR           $(dynamic_symbol_addr pipe | format 16)"
echo "#define select_ADDR         $(dynamic_symbol_addr select | format 16)"
echo "#define fork_ADDR           $(dynamic_symbol_addr fork | format 16)"
echo "#define execv_ADDR          $(dynamic_symbol_addr execv | format 16)"
echo "#define system_ADDR         $(dynamic_symbol_addr system | format 16)"
echo "#define pthread_create_ADDR $(dynamic_symbol_addr pthread_create | format 16)"
echo "#define qemu_set_irq_ADDR   $(static_symbol_addr qemu_set_irq | format 16)"
echo ""
echo "#define property_get_alias_ADDR          $(static_symbol_addr property_get_alias | format 16)"
echo "#define property_get_enum_ADDR           $(static_symbol_addr property_get_enum | format 16)"
echo "#define property_get_tm_ADDR             $(static_symbol_addr property_get_tm | format 16)"
echo "#define property_get_uint32_ptr_ADDR     $(static_symbol_addr property_get_uint32_ptr | format 16)"
echo "#define property_get_uint8_ptr_ADDR      $(static_symbol_addr property_get_uint8_ptr | format 16)"
echo "#define property_get_bool_ADDR           $(static_symbol_addr property_get_bool | format 16)"
echo "#define property_get_str_ADDR            $(static_symbol_addr property_get_str | format 16)"
echo "#define property_get_uint8_ptr_ADDR      $(static_symbol_addr property_get_uint8_ptr | format 16)"
echo "#define property_get_uint16_ptr_ADDR     $(static_symbol_addr property_get_uint16_ptr | format 16)"
echo "#define property_get_uint32_ptr_ADDR     $(static_symbol_addr property_get_uint32_ptr | format 16)"
echo "#define property_get_uint64_ptr_ADDR     $(static_symbol_addr property_get_uint64_ptr | format 16)"
echo "#define object_get_link_property_ADDR    $(static_symbol_addr object_get_link_property | format 16)"
echo "#define object_get_child_property_ADDR   $(static_symbol_addr object_get_child_property | format 16)"
echo "#define memory_region_get_size_ADDR      $(static_symbol_addr memory_region_get_size | format 16)"
echo "#define memory_region_get_addr_ADDR      $(static_symbol_addr memory_region_get_addr| format 16)"
echo "#define memory_region_get_container_ADDR $(static_symbol_addr memory_region_get_container | format 16)"
echo "#define memory_region_get_priority_ADDR  $(static_symbol_addr memory_region_get_priority | format 16)"
echo ""
echo "#define property_set_str_ADDR         $(static_symbol_addr property_set_str | format 16)"
echo "#define property_set_bool_ADDR        $(static_symbol_addr property_set_bool | format 16)"
echo "#define property_set_enum_ADDR        $(static_symbol_addr property_set_enum | format 16)"
echo "#define property_set_alias_ADDR       $(static_symbol_addr property_set_alias | format 16)"
echo "#define object_set_link_property_ADDR $(static_symbol_addr object_set_link_property | format 16)"
echo ""
echo "#define memory_region_resolve_container_ADDR $(static_symbol_addr memory_region_resolve_container | format 16)";
echo "#define object_resolve_child_property_ADDR   $(static_symbol_addr object_resolve_child_property | format 16)";
echo "#define object_resolve_link_property_ADDR    $(static_symbol_addr object_resolve_link_property | format 16)";
echo "#define object_resolve_child_property_ADDR   $(static_symbol_addr object_resolve_child_property | format 16)";
echo "#define property_resolve_alias_ADDR          $(static_symbol_addr property_resolve_alias | format 16)";
echo ""
echo "#define property_release_alias_ADDR         $(static_symbol_addr property_release_alias | format 16)"
echo "#define property_release_bootindex_ADDR     $(static_symbol_addr property_release_bootindex | format 16)"
echo "#define property_release_str_ADDR           $(static_symbol_addr property_release_str | format 16)"
echo "#define property_release_bool_ADDR          $(static_symbol_addr property_release_bool | format 16)"
echo "#define property_release_enum_ADDR          $(static_symbol_addr property_release_enum | format 16)"
echo "#define property_release_tm_ADDR            $(static_symbol_addr property_release_tm | format 16)"
echo "#define object_release_link_property_ADDR   $(static_symbol_addr object_release_link_property | format 16)"
echo "#define object_finalize_child_property_ADDR $(static_symbol_addr object_finalize_child_property | format 16)"
echo ""

